FROM public.ecr.aws/ubuntu/ubuntu:18.04

LABEL maintainer="Amazon AI"
# Specify LABEL for inference pipelines to use SAGEMAKER_BIND_TO_PORT
# https://docs.aws.amazon.com/sagemaker/latest/dg/inference-pipeline-real-time.html
LABEL com.amazonaws.sagemaker.capabilities.accept-bind-to-port=true
LABEL com.amazonaws.sagemaker.capabilities.multi-models=true

# Add arguments to achieve the version, python and url
ARG PYTHON=python3.7
ARG PIP="python3.7 -m pip"
ARG TFS_SHORT_VERSION=2.5.3
ARG TF_S3_URL=https://tensorflow-aws.s3-us-west-2.amazonaws.com

# See http://bugs.python.org/issue19846
ENV LANG=C.UTF-8
# Python won’t try to write .pyc or .pyo files on the import of source modules
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV SAGEMAKER_TFS_VERSION="${TFS_SHORT_VERSION}"
ENV PATH="$PATH:/sagemaker"
ENV LD_LIBRARY_PATH='/usr/local/lib:$LD_LIBRARY_PATH'
ENV MODEL_BASE_PATH=/models
# The only required piece is the model name in order to differentiate endpoints
ENV MODEL_NAME=model
# To prevent user interaction when installing time zone data package
ENV DEBIAN_FRONTEND=noninteractive

# nginx + njs
RUN apt-get update \
 && apt-get -y install --no-install-recommends \
    curl \
    gnupg2 \
    ca-certificates \
    git \
    wget \
    vim \
 && curl -s http://nginx.org/keys/nginx_signing.key | apt-key add - \
 && echo 'deb http://nginx.org/packages/ubuntu/ bionic nginx' >> /etc/apt/sources.list \
 && apt-get update \
 && apt-get -y install --no-install-recommends \
    nginx \
    nginx-module-njs \
  && apt-get install software-properties-common -y \
  && add-apt-repository ppa:deadsnakes/ppa \
  && apt-get update \
  && apt-get install python3.7 -y \
  && apt-get install python3-distutils -y \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

RUN echo "deb https://apt.repos.neuron.amazonaws.com bionic main" | tee /etc/apt/sources.list.d/neuron.list && \
    wget -qO - https://apt.repos.neuron.amazonaws.com/GPG-PUB-KEY-AMAZON-AWS-NEURON.PUB | apt-key add - && \
    apt-get update && \
    apt-get install "tensorflow-model-server-neuron=2.5.4.2.3.0.0" \
            aws-neuron-tools && \
    rm -rf /var/lib/apt/lists/*

RUN apt list -a tensorflow-model-server-neuron

RUN wget https://bootstrap.pypa.io/get-pip.py
RUN python3.7 get-pip.py  

# cython, falcon, gunicorn, grpc
RUN python3.7 -m pip install --no-cache-dir \
    awscli \
    boto3 \
    pyYAML==5.3.1 \
    cython==0.29.12 \
    falcon==2.0.0 \
    gunicorn==19.9.0 \
    gevent==1.4.0 \
    greenlet==0.4.14 \
    requests==2.22.0 \
    grpcio==1.24.1 \
    protobuf==3.10.0 \
# using --no-dependencies to avoid installing tensorflow binary
 && python3.7 -m pip install --no-dependencies --no-cache-dir \
    tensorflow-serving-api==2.5.3

RUN python3.7 -m pip install --extra-index-url=https://pip.repos.neuron.amazonaws.com --no-cache-dir "tensorflow-neuron==2.5.3.2.3.0.0"

COPY sagemaker /sagemaker

WORKDIR /

# Some TF tools expect a "python" binary
RUN ln -s $(which ${PYTHON}) /usr/local/bin/python \
 && ln -sf $(which ${PYTHON}) $(which python3) \
 && ln -s /usr/local/bin/pip3 /usr/bin/pip

RUN curl ${TF_S3_URL}/MKL-Libraries/libiomp5.so -o /usr/local/lib/libiomp5.so \
 && curl ${TF_S3_URL}/MKL-Libraries/libmklml_intel.so -o /usr/local/lib/libmklml_intel.so

# Expose ports
# gRPC and REST
EXPOSE 8500 8501

# Set where models should be stored in the container
RUN mkdir -p ${MODEL_BASE_PATH}

# Create a script that runs the model server so we can use environment variables
# while also passing in arguments from the docker command line
RUN echo '#!/bin/bash \n\n' > /usr/bin/tf_neuron_serving_entrypoint.sh \
 && echo '/usr/local/bin/tensorflow_model_server_neuron --port=8500 --rest_api_port=8501 --model_name=${MODEL_NAME} --model_base_path=${MODEL_BASE_PATH}/${MODEL_NAME} "$@"' >> /usr/bin/tf_neuron_serving_entrypoint.sh \
 && chmod +x /usr/bin/tf_neuron_serving_entrypoint.sh

ENV PATH="/opt/aws/neuron/bin:${PATH}"

ADD https://raw.githubusercontent.com/aws/aws-deep-learning-containers-utils/master/deep_learning_container.py /usr/local/bin/deep_learning_container.py

RUN chmod +x /usr/local/bin/deep_learning_container.py

RUN curl https://aws-dlc-licenses.s3.amazonaws.com/tensorflow/license.txt -o /license.txt

CMD ["/usr/bin/tf_neuron_serving_entrypoint.sh"]
